<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div class="cintainer">
        <button id="primary">发送请求</button>
        <button id="warning">取消请求</button>
    </div>
    <script>
        // 构造函数
        function Axios(config) {
            this.config = config
        }
        // 原型 request 方法
        Axios.prototype.request = function (config) {
            return dispatchReuest(config)
        }
        // dispatchRquest() 函数
        function dispatchReuest(config) {
            return xhrAdapter(config)
        }
        // xhrAdapter
        function xhrAdapter(config) {
            // 发送 ajax 请求
            return new Promise((resolve, reject) => {
                // 实例化对象
                const xhr = new XMLHttpRequest()
                xhr.open(config.method, config.url)
                xhr.send()
                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4) {
                        if (xhr.status >= 200 && xhr.status < 300) {
                            resolve({
                                status: xhr.status,
                                statusText: xhr.statusText
                            })
                        } else {
                            // reject(new Error('请求失败'))
                        }
                    }
                }
                // 取消请求的处理
                if (config.cancelToken) {
                    config.cancelToken.promise.then(resolve => {
                        xhr.abort()
                        reject(new Error('请求已经被取消'))
                    })
                }
            })
        }

        // 创建 axios 函数
        const context = new Axios({})
        const axios = Axios.prototype.request.bind(context)
        axios.CancelToken = CancelToken

        // CancelToken 构造函数
        function CancelToken(executor) {
            // 声明一个变量
            let resolvePromise
            // 为实例对象添加属性
            this.promise = new Promise((resolve) => {
                resolvePromise = resolve
            })
            // 调用 executor 函数
            executor(function () {
                // 执行 resolvePromise 函数
                resolvePromise()
            })
        }

        const btns = document.querySelectorAll('button')
        let cancel = null
        btns[0].onclick = () => {
            // 检测上一次请求是否完成
            if (cancel !== null) {
                // 取消上一次请求
                cancel()
            }
            axios({
                method: 'GET',
                url: 'http://www.liulongbin.top:3007/my/article/cates',
                // 创建 cancelToken 值
                cancelToken: new axios.CancelToken(function (c) {
                    // 将 c 的值赋给 cancel
                    cancel = c
                })
            }).then(response => {
                console.log(response);
                cancel = null
            })
        }

        btns[1].onclick = () => {
            cancel()
        }
    </script>
</body>

</html>